<?php
namespace app\common\model;

class Building extends \think\Model
{
    /**
     * 数据的盐,此值如果要修改需要前后端一起改
     */
    const SALT = "it's a salt";

    protected $pk="name";

    /**
     * 模型输出时应当隐藏的数据
     *
     * @var array
     */
    //protected $hidden = ['key'];

    /**
     * 解密一个加密的Key,此Key加密时采用的时间戳建议使用服务器接口获取时间戳
     *
     * @param string $keyY 待解密的秘钥
     * @param int $expire 有效期(秒)
     * @return false|string 失败返回false，成功则返回解密后到的bkey(电脑hash)
     */
    public static function decodeKey(string $keyY, int $expire)
    {
        if (\count_chars($keyY) <= 40) {
            return false; //小于40的长度一定是错误的秘钥
        }
        $time = hexdec(substr($keyY, 40)); //时间戳
        if (time() - $time > $expire) {
            return false; //先检查是否在有效期内
        }

        $idY = substr($keyY, 0, 32);
        $hash = substr($keyY, 32, 8);

        if (!preg_match("/[0-9A-Fa-f]{32}/", $idY) || !preg_match("/[0-9A-Fa-f]{8}/", $hash)) {
            return false;
        }

        $idYs = str_split(strtolower($idY));
        $hashs = str_split(strtolower($hash));

        for ($i = 0; $i < 8; $i++) {
            $hashs[$i] = ord($hashs[$i]) - (ord($hashs[$i]) >= 97 ? 87 : 48);
        }

        for ($i = 0; $i < 32; $i++) {
            $val = ord($idYs[$i]);
            $val -= $val >= 97 ? 87 : 48;
            $val = ($val + 16 - $hashs[$i % 8]) % 16;
            $idYs[$i] = chr($val + ($val >= 10 ? 87 : 48));
        }
        $idX = implode("", $idYs); //解密后的ID

        $newSign = substr(md5($idX . Building::SALT . $time), 24, 8);
        if ($newSign === $hash) {
            return $idX;
        } else {
            return false;
        }
    }

    /**
     * 根据bkey获取教学楼对象
     *
     * @return void
     */
    public static function getByKey($bkey, int $expire){
        if ($key=Building::decodeKey($bkey,$expire)){
            return Building::where('key',$key)->find();
        } else {
            return null;
        }
    }

}
